import { ElementOf } from './../../react/antd-demo/packages/util/src/type';
/*
 * @Descripttion: 
 * @Author: ziwei
 * @Date: 2022-07-06 17:29:24
 * @LastEditors: ziwei
 * @LastEditTime: 2022-07-06 23:23:31
 */
export{}
interface Fish{
    name1:string
}
interface Water{
    name2:string
}
interface Bird{
    name3:string
}
interface Sky{
    name4:string
}
type Condition<T> = T extends Fish?Water:Sky
//let con:Condition<Fish> = {name2:'水'}

//条件类型的分发
let con1:Condition<Fish|Bird> = {name2:''};
let con2:Condition<Fish|Bird> = {name4:''};

//条件类型有一个特征【分布式有条件类型】，但是分布式有条件类型是有前提的，条件类型里待检查的类型必须是naked type param
//T[]
//type Condition<T> = [T] extends Fish[]?Water:Sky
//type Condition<T> = {T} extends {t:Fish}?Water:Sky

//找出T中不包含U的部分
type Diff<T,U> = T extends U?never:T
type R = Diff<'a'|'b'|'c'|'d','a'|'b'|'c'>  //d

type Filter<T,U> = T extends U?T:never
type R3 = Filter<'a'|'b'|'c'|'d','a'|'b'|'c'> // a b c

//内置类型
//Exclude
type Exclude<T,U> = T extends U?never:T
type R4 = Diff<'a'|'b'|'c'|'d','a'|'b'|'c'>

//Extract
type Extract<T, U> = T extends U ? T : never;
type R5 = Extract<'a'|'b'|'c'|'d','a'|'b'|'c'>

//NonNullable
type NonNullable<T> = T extends null | undefined ? never : T
type R6 = NonNullable<'a'|null|undefined>

//ReturnType
//infer推倒
type ReturnType<T>  =T extends (...args:any[])=>infer R?R:T;
function getUser() {
    return {name:"xx",age:10}
}
type GetUserType = typeof getUser
// type ReturnUser = ReturnType<GetUserType>
// let u:ReturnUser = {
//     name:'xx',
//     age:10
// }

/**
 * Obtain the parameters of a function type in a tuple
 * p = [string,number]
 */
type Parameters<T> = T extends (...args: infer P) => any ? P : never;
type ParamsType = Parameters<GetUserType>

//InstanceType
class Person8{
    name:string
    constructor(name:string){
        this.name = name
    }
    getName(){
        console.log(this.name)
    }
}
//获取类的构造函数参数类型 info 相当于变量赋值ts内部做的
type ConstructorParamters<T extends abstract new (...args: any) => any> = T extends abstract new (...args: infer P) => any ? P : never;
type Params = ConstructorParameters<typeof Person8>

type InstanceType<T extends abstract new (...args: any) => any> = T extends abstract new (...args: any) => infer R ? R : any;
type Person8Instance = InstanceType<typeof Person8>
let instance:Person8Instance={
    name:'zf',
    getName(){}
}

//infer应用案例 元祖转元祖类型
//tuple转union
type ElementOf<T> = T extends Array<infer E>?E:never;
type Ttuple = [string,number]
type TupleToUnion = ElementOf<Ttuple>;//string|number

//联合类型转成交叉类型
//string|number => string&number
type T1 = {name:string}
type T2 = {age:number}
type ToIntersection<T> = T extends {a:(x:infer U)=>void,b:(x:infer U)=>void}?U:never;
type T3 = ToIntersection<{a:(x:T1)=>void,b:(x:T2)=>void}>